﻿using System;
using System.Net;
using System.Collections.Generic;
using System.Text;

public class StringEncoder
{
    private Queue<bool> m_queue = new Queue<bool>();

    public void EnqueueBits(int value, int bits)
    {
        for (int i = 0; i < bits; i++) m_queue.Enqueue(((value >> i) & 1) == 1);
    }

    public void EnqueueAlphaNum(char ch)
    {
        int value =
            (ch >= 'a' && ch <= 'z') ? ch - 'a'
            : (ch >= 'A' && ch <= 'Z') ? 26 + ch - 'A'
            : (ch >= '0' && ch <= '9') ? 52 + ch - '0'
            : (ch >= '_') ? 62
            : (ch >= '-') ? 63
            : 0;

        EnqueueBits(value, 6);
    }

    public int DequeueBits(int bits)
    {
        int value = 0;
        for (int i = 0; i < bits; i++)
        {
            if (m_queue.Count == 0) break;
            int digitMask = (m_queue.Dequeue() ? 1 : 0) << i;
            value |= digitMask;
        }
        return value;
    }

    public char DequeueAlphaNum()
    {
        int value = DequeueBits(6);
        if (value < 26) return (char)(value + 'a');
        else if (value < 52) return (char)(value - 26 + 'A');
        else if (value < 62) return (char)(value - 52 + '0');
        else if (value == 62) return '_';
        else return '-';
    }

    public string AllToString()
    {
        StringBuilder sb = new StringBuilder();
        while (m_queue.Count > 0)
        {
            sb.Append(DequeueAlphaNum());
        }
        return sb.ToString();
    }
}